﻿using System.Collections.Generic;
using System.Threading.Tasks;

namespace BlamanticUI.Components;

/// <summary>
/// Represents a modal displays content that temporarily blocks interactions with the main view of a site.
/// </summary>
[CssClass("modal")]
public class Modal : BlazorChildContentComponentBase, IHasUIComponent, IHasSize, IHasBasic, IHasInverted, IHasOnActive
{
    /// <summary>
    /// Initializes a new instance of the <see cref="Modal"/> class.
    /// </summary>
    public Modal()
    {
        Closable = true;
    }

    /// <summary>
    /// Gets or sets UI content of header.
    /// </summary>
    [Parameter] public RenderFragment HeadContent { get; set; }

    /// <summary>
    /// Gets or sets UI content of footer.
    /// </summary>
    [Parameter] public RenderFragment FootContent { get; set; }
    /// <summary>
    /// Gets or sets the size of modal.
    /// </summary>
    [Parameter] [CssClass(Order = 5)] public Size? Size { get; set; }
    /// <summary>
    /// Gets or sets a value indicating whether modal is full width display.
    /// </summary>
    [Parameter] [CssClass("fullscreen")] public bool FullWidth { get; set; }
    /// <summary>
    /// Gets or sets a value indicating whether modal is full screen display.
    /// </summary>
    [Parameter] [CssClass("overlay fullscreen")] public bool FullScreen { get; set; }
    /// <summary>
    /// Gets or sets a value indicating whether this style is basic.
    /// </summary>
    [Parameter] public bool Basic { get; set; }
    /// <summary>
    /// Gets or sets a value indicating whether adapted inverted background by parent component.
    /// </summary>
    /// <value>
    ///   <c>true</c> if adapted; otherwise, <c>false</c>.
    /// </value>
    [Parameter] [CssClass("inverted", Order = 10)] public bool Inverted { get; set; }
    /// <summary>
    /// Gets or sets a value indicating whether the content in body can be scrolled while the height is out of bound.
    /// </summary>
    /// <value>
    ///   <c>true</c> if scrollable; otherwise, <c>false</c>.
    /// </value>
    [Parameter] public bool Scrollable { get; set; }
    /// <summary>
    /// Gets or sets a value indicating whether the content has image at left.
    /// </summary>
    [Parameter] public bool ImageContent { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether this <see cref="Modal"/> is closable.
    /// </summary>
    [Parameter] public bool Closable { get; set; }

    /// <summary>
    /// Gets or sets a value indicating whether this state is actived.
    /// </summary>
    /// <value>
    ///   <c>true</c> if actived; otherwise, <c>false</c>.
    /// </value>
    [Parameter] public bool Active { get; set; }

    /// <summary>
    /// Gets or sets the alignment position of modal.
    /// </summary>
    [Parameter] [CssClass(" aligned", Suffix = true)] public VerticalPosition? Alignment { get; set; }
    public EventCallback<bool> OnActive { get; set; }

    public void ActiveModal(bool active = true)
    {
        Active = active;
        StateHasChanged();
    }

    /// <summary>
    /// Renders the component to the supplied <see cref="T:Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder" />.
    /// </summary>
    /// <param name="builder">A <see cref="T:Microsoft.AspNetCore.Components.Rendering.RenderTreeBuilder" /> that will receive the render output.</param>
    protected override void BuildRenderTree(RenderTreeBuilder builder)
    {
        builder.CreateComponent<Dimmer>(0, BuildModal, new
        {
            FullScreen = true,
            Active,
            Inverted,
            tagindex = -1,
            onkeyup = EventCallback.Factory.Create<KeyboardEventArgs>(this, PreseEsc),
            AdditionalCssClass = Alignment.HasValue ? "modals" : null
        });

        //builder.OpenComponent<Dimmer>(0);
        //builder.AddAttribute(1, nameof(Dimmer.FullScreen), true);
        //builder.AddAttribute(2, nameof(Dimmer.Active), Active);
        //builder.AddAttribute(3, nameof(Dimmer.Inverted), Inverted);
        //if (Alignment.HasValue)
        //{
        //    builder.AddAttribute(4, nameof(Dimmer.AdditionalCssClass), "modals");
        //}

        //builder.AddAttribute(8, nameof(Dimmer.ChildContent), (RenderFragment)BuildModal);
        //builder.AddAttribute(8, "tabindex", 0);
        //builder.AddAttribute(9, "onkeyup", );
        ////base.AddComponentReference(builder);
        //builder.CloseComponent();
    }

    /// <summary>
    /// Builds the modal.
    /// </summary>
    /// <param name="builder">The builder.</param>
    private void BuildModal(RenderTreeBuilder builder)
    {
        builder.OpenElement(0, "div");
        base.BuildComponentAttributes(builder, out int sequence);

        builder.CreateComponent<Icon>(sequence + 1, attributes: new
        {
            IconClass = "close",
            onclick = EventCallback.Factory.Create<MouseEventArgs>(this, e => this.Activate(false))
        }, condition: Closable);

        builder.CreateElement(sequence + 2, "div", HeadContent, new { @class = "header" }, HeadContent is not null);

        builder.CreateElement(sequence + 3, "div", ChildContent, new
        {
            @class = HtmlHelper.CreateCssBuilder().Append("scrolling", Scrollable)
                                            .Append("image", ImageContent)
                                            .Append("content")
        });

        builder.CreateElement(sequence + 4, "div", FootContent, new { @class = "actions" }, FootContent is not null);

        builder.CloseElement();
    }
    /// <summary>
    /// Preses the escape.
    /// </summary>
    /// <param name="e">The <see cref="KeyboardEventArgs"/> instance containing the event data.</param>
    async Task PreseEsc(KeyboardEventArgs e)
    {
        if (e?.Code?.ToLower() == "escape")
        {
            await this.Activate(false);
        }
    }
}
